/**
 * Copyright (C) 2008 Mathieu Carbou
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.code.mojo.license.header;

import static com.google.code.mojo.license.util.FileUtils.*;

import java.util.regex.Pattern;

/**
 * <b>Date:</b> 17-Feb-2008<br>
 * <b>Author:</b> Mathieu Carbou (mathieu.carbou@gmail.com)
 */
public enum HeaderType
{
    ////////// COMMENT TYPES //////////



    //              FirstLine           Before              EndLine             SkipLine                    FirstLineDetection              LastLineDetection
    //generic
    JAVADOC_STYLE   ("/**",             " * ",              " */",              null,                       "(\\s|\\t)*/\\*.*$",            ".*\\*/(\\s|\\t)*$"),
    SCRIPT_STYLE    ("#",               "# ",               "#",                "^#!.*$",                   "#$",                           "#$"),
    XML_STYLE       ("<!--" + eol(),    "    ",             eol() + "-->",      "^<\\?xml.*>$",             "(\\s|\\t)*<!--.*$",            ".*-->(\\s|\\t)*$"),
    SEMICOLON_STYLE (";",               "; ",               ";",                null,                       ";$",                           ";$"),
    APOSTROPHE_STYLE("'",               "' ",               "'",                null,                       "'$",                           "'$"),
    EXCLAMATION_STYLE("!",              "! ",               "!",                null,                       "!$",                           "!$"),
    DOUBLEDASHES_STYLE("--",            "-- ",              "--",               null,                       "--$",                          "--$"),
    SLASHSTAR_STYLE("/*",               " * ",              " */",              null,                       "(\\s|\\t)*/\\*.*$",            ".*\\*/(\\s|\\t)*$"),
    BRACESSTAR_STYLE("\\{*",            " * ",              " *\\}",            null,                       "(\\s|\\t)*\\{\\*.*$",          ".*\\*\\}(\\s|\\t)*$"),
    SHARPSTAR_STYLE ("#*",              " * ",              " *#",              null,                       "(\\s|\\t)*#\\*.*$",            ".*\\*#(\\s|\\t)*$"),
    DOUBLETILDE_STYLE("~~",             "~~ ",              "~~",               null,                       "~~$",                          "~~$"),
    DYNASCRIPT_STYLE("<%--" + eol(),    "    ",             eol() + "--%>",     null,                       "(\\s|\\t)*<%--.*$",            ".*--%>(\\s|\\t)*$"),
    DYNASCRIPT3_STYLE("<!---" + eol(),  "    ",             eol() + "--->",     null,                       "(\\s|\\t)*<!---.*$",           ".*--->(\\s|\\t)*$"),
    PERCENT3_STYLE  ("%%%",             "%%% ",             "%%%",              null,                       "%%%$",                         "%%%$"),
    EXCLAMATION3_STYLE("!!!",           "!!! ",             "!!!",              null,                       "!!!$",                         "!!!$"),

    DOUBLESLASH_STYLE("//",             "// ",              "//",               null,                       "//$",                          "//$"),
    // non generic
    PHP             ("/*",              " * ",              " */",              "^<\\?php.*$",              "(\\s|\\t)*/\\*.*$",            ".*\\*/(\\s|\\t)*$"),
    ASP             ("<%",              "' ",               "%>",               null,                       "(\\s|\\t)*<%[^@].*$",          ".*%>(\\s|\\t)*$"),
    LUA             ("--[[",            "",                 "]]",               null,                       "--\\[\\[$",                    "\\]\\]$"),
    FTL             ("<#--" + eol(),    "    ",             eol() + "-->",      "\\[#ftl(\\s.*)?\\]",       "(\\s|\\t)*<#--.*$",            ".*-->(\\s|\\t)*$"),
    FTL_ALT         ("[#--" + eol(),    "    ",             eol() + "--]",      "\\[#ftl(\\s.*)?\\]",       "(\\s|\\t)*\\[#--.*$",          ".*--\\](\\s|\\t)*$"),
    TEXT            ("====",            "    ",             "====",             null,                       "====$",                        "====$"),
    BATCH           ("@REM",            "@REM ",            "@REM",             null,                       "@REM$",                        "@REM$"),
    // unknown
    UNKNOWN         ("",                "",                 "",                 null,                       null,                           null);

    ////////////////////////////////////

    private final String firstLine;
    private final String beforeEachLine;
    private final String endLine;

    private final Pattern skipLinePattern;
    private final Pattern firstLineDetectionPattern;
    private final Pattern endLineDetectionPattern;

    private HeaderType(String firstLine, String beforeEachLine, String endLine, String skipLinePattern, String firstLineDetectionPattern, String endLineDetectionPattern)
    {
        this.firstLine = firstLine;
        this.beforeEachLine = beforeEachLine;
        this.endLine = endLine;
        this.skipLinePattern = compile(skipLinePattern);
        this.firstLineDetectionPattern = compile(firstLineDetectionPattern);
        this.endLineDetectionPattern = compile(endLineDetectionPattern);
    }

    private Pattern compile(String regexp)
    {
        return regexp == null ? null : Pattern.compile(regexp);
    }

    public String getFirstLine()
    {
        return firstLine;
    }

    public String getBeforeEachLine()
    {
        return beforeEachLine;
    }

    public String getEndLine()
    {
        return endLine;
    }

    public boolean mustSkip(String line)
    {
        return skipLinePattern != null && line != null && skipLinePattern.matcher(line).matches();
    }

    public boolean isFirstHeaderLine(String line)
    {
        return firstLineDetectionPattern != null && line != null && firstLineDetectionPattern.matcher(line).matches();
    }

    public boolean isLastHeaderLine(String line)
    {
        return endLineDetectionPattern != null && line != null && endLineDetectionPattern.matcher(line).matches();
    }

    public static HeaderType fromName(String name)
    {
        for(HeaderType type : values())
        {
            if(type.name().equalsIgnoreCase(name))
            {
                return type;
            }
        }
        return UNKNOWN;
    }

}
